<?php

namespace catchAdmin\permissions\controller;

use app\common\model\RoleHasDepartments;
use catchAdmin\permissions\model\Permissions;
use catchAdmin\permissions\model\Roles;
use catcher\base\CatchRequest as Request;
use catcher\base\CatchController;
use catcher\CatchResponse;
use catcher\exceptions\FailedException;
use catcher\Utils;
use think\response\Json;
use catchAdmin\permissions\model\Roles as RoleModel;
use catchAdmin\permissions\model\UserHasRoles;
use Overtrue\Pinyin\Pinyin;

class Role extends CatchController
{
    protected $role;

    public function __construct(RoleModel $role)
    {
        $this->role = $role;
    }

    /**
     *
     * @time 2019年12月09日
     * @return string|Json
     */
    public function index()
    {
        return CatchResponse::success($this->role->getList());
    }

    /**
     *
     * @time 2019年12月11日
     * @param Request $request
     * @return Json
     * @throws \think\db\exception\DbException
     */
    public function save(Request $request)
    {
        $params = $request->param();

        //角色名称不能重复
        $role = (new Roles())->where('role_name', $params['role_name'])->findOrEmpty();
        if (!$role->isEmpty()) {
            throw new FailedException('角色名称不能重复');
        }

	//生成角色标识，拼音字母首拼
        $params['identify'] = (new Pinyin())->abbr($params['role_name']);

        $user = request()->user();
        $roles = $user->roles->toArray();
        $roleIds = array_column($roles, "id");

        if (Roles::where('identify', $params['identify'])->find()) {
            throw new FailedException('角色标识 [' . $params['identify'] . ']已存在');
        }
        if (!empty($roleIds)) {
            $params["parent_roles"] = implode(",", $roleIds);
        }


        $this->role->storeBy($params);
        // 分配权限
        if ($params["data_range"] === Roles::ALL_DATA && !Utils::isSuperAdmin()) {

            if (!empty($roles)) {
                if (!empty($roleIds)) {
                    # 获取对应的部门Id
                    $deptIds = (new RoleHasDepartments())->where([["role_id", "in", $roleIds]])->column("department_id");
                    if (!empty($deptIds)) {
                        $params["departments"] = $deptIds;
                    }
                }
            }
        } else {
            if (count($params['permissions'])) {
                $this->role->attachPermissions(array_unique($params['permissions']));
            }
        }
        // 分配部门
        if (isset($params['departments']) && count($params['departments'])) {
            $this->role->attachDepartments($params['departments']);
        }
        // 添加角色
        return CatchResponse::success();
    }

    public function read($id)
    {
        $role = $this->role->findBy($id);
        $role->permissions = $role->getPermissions();
        $role->departments = $role->getDepartments();
        return CatchResponse::success($role);
    }

    /**
     *
     * @time 2019年12月11日
     * @param $id
     * @param Request $request
     * @return Json
     * @throws \think\db\exception\DbException
     */
    public function update($id, Request $request): Json
    {
        $params = $request->put();
        unset($params["creator_id"]);
//        if (Roles::where('identify', $request->param('identify'))->where('id', '<>', $id)->find()) {
//            throw new FailedException('角色标识 [' . $request->param('identify') . ']已存在');
//        }

        $this->role->updateBy($id, $params);
        $role = $this->role->findBy($id);
        if ($params["data_range"] === Roles::ALL_DATA && !Utils::isSuperAdmin()) {
            $user = request()->user();
            $roles = $user->roles->toArray();
            if (!empty($roles)) {
                $roleIds = array_column($roles, "id");
                if (!empty($roleIds)) {
                    # 获取对应的部门Id
                    $deptIds = (new RoleHasDepartments())->where([["role_id", "in", $roleIds]])->column("department_id");
                    if (!empty($deptIds)) {
                        $params["departments"] = $deptIds;
                    }
                }
            }
        }

        $hasPermissionIds = $role->getPermissions()->column('id');

        $permissionIds = $request->param('permissions');

        // 已存在权限 IDS
        $existedPermissionIds = [];
        foreach ($hasPermissionIds as $hasPermissionId) {
            if (in_array($hasPermissionId, $permissionIds)) {
                $existedPermissionIds[] = $hasPermissionId;
            }
        }

        $attachIds = array_diff($permissionIds, $existedPermissionIds);

        $detachIds = array_diff($hasPermissionIds, $existedPermissionIds);

        if (!empty($detachIds)) {
            $role->detachPermissions($detachIds);
        }
        if (!empty($attachIds)) {
            $role->attachPermissions(array_unique($attachIds));
        }

        // 更新department
        $hasDepartmentIds = $role->getDepartments()->column('id');

        //$departmentIds = $request->param('departments',[]);
        $departmentIds = $params['departments'] ?? [];

        // 已存在部门 IDS
        $existedDepartmentIds = [];
        foreach ($hasDepartmentIds as $hasDepartmentId) {
            if (in_array($hasDepartmentId, $departmentIds)) {
                $existedDepartmentIds[] = $hasDepartmentId;
            }
        }

        $attachDepartmentIds = array_diff($departmentIds, $existedDepartmentIds);
        $detachDepartmentIds = array_diff($hasDepartmentIds, $existedDepartmentIds);


        if (!empty($detachDepartmentIds)) {
            $role->detachDepartments($detachDepartmentIds);
            # 判断当前角色id是谁创建的，然后读取一下最新的权限
            if ($role["parent_roles"] !== "") {
                $createRoleIds = $this->role->whereRaw("FIND_IN_SET('" . $role['id'] . "', parent_roles)")->select();
                if (!empty($createRoleIds)) {
                    #执行删除操作
                    foreach ($createRoleIds as $k => $v) {
                        $v->detachDepartments($detachDepartmentIds);
                    }
                }
            }

        }
        if (!empty($attachDepartmentIds)) {
            $role->attachDepartments(array_unique($attachDepartmentIds));
        }

        return CatchResponse::success();
    }

    /**
     *
     * @time 2019年12月11日
     * @param $id
     * @return Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws FailedException
     */
    public function delete($id): Json
    {
        $has = (new UserHasRoles())->where('role_id', $id)->value('id');

        if ($has) {
            throw new FailedException('存在绑定的用户，无法删除');
        }

//        if ($this->role->where('parent_id', $id)->find()) {
//            throw new FailedException('存在子角色，无法删除');
//        }
        $role = $this->role->findBy($id);
        // 删除权限
        $role->detachPermissions();
        // 删除部门关联
        $role->detachDepartments();
        // 删除用户关联
        $role->users()->detach();
        // 删除
        $this->role->deleteBy($id);

        return CatchResponse::success();
    }

    /**
     * 获取角色权限
     *
     * @time 2021年07月29日
     * @param $id
     * @return Json
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\db\exception\DataNotFoundException
     */
    public function getPermissions($id): Json
    {
        $permissionIds = $this->role->findBy($id)->getPermissions()->column('id');

        if (!count($permissionIds)) {
            $permissions = Permissions::field(['id', 'parent_id', 'permission_name'])->select()->toTree();
        } else {
            $permissions = Permissions::whereIn('id', $permissionIds)->field(['id', 'parent_id', 'permission_name'])->select()->toTree();

        }

        return CatchResponse::success($permissions);
    }
}
